#pragma once

#include "GetEphemInterface.h"

class CEphemEPM: public IGetCoord
{
	enum {ERROR_BUFFER_SIZE = 256};
public:
	class CError 
	{
		public: 
			CError() { strcpy(m_stzError, "Unknown"); };
			CError(LPCTSTR stzError) { strcpy(m_stzError, stzError); };

			LPCTSTR GetError() const { return m_stzError; };
		protected: 
			TCHAR m_stzError[ERROR_BUFFER_SIZE]; 
	}; 
	class CErrorNoFile: public CError 
	{
		public:	CErrorNoFile(LPCTSTR stzFileName) { sprintf(m_stzError, "can not found file: (%s)", stzFileName); };
	};
	class CErrorOutOfRange: public CError 
	{ 
		public:	CErrorOutOfRange(double dJd) { sprintf(m_stzError, "date %d out of ephemerid range", dJd); };
	};

protected:
	class CSingleBody
	{
	public:
		class CErrorAlreadyInit: public CError 
		{
			public: CErrorAlreadyInit() { sprintf(m_stzError, "this ephem already init"); }; 
		};
		class CErrorNotInit: public CError 
		{
			public: CErrorNotInit() { sprintf(m_stzError, "this ephem not init yet"); };
		};

	public:
		CSingleBody();
		bool InitTxt(LPCTSTR stzTxtFilePath);
		bool InitBin(LPCTSTR stzBinFilePath);

		double GetMass() const;
		void SetMass(double dMass);

		int calc(double dJdt, double* xv, double *vv, double *dMass = NULL, bool bGetVelocity = true);
	protected:
	
		double calc_vel(double *pCoef, double* tt);
		double calc_pos(double *pCoef, double* xx, double dlt);
		void calc_cheb_pol(double td, double *tt, double *xx);
	protected:
		double	m_dMass;	

		double	m_dJdt;			//initial Julian date 
		double  m_dDelta;		//approximation subinterval
		int		m_nCoef;		//number of (polunomial degrees + free term)
		int		m_nDim;			//number of dimensions
		int		m_nBl;			//number of subintervals
		vector<double>	m_vecCoef;
		
	};
	typedef vector<CSingleBody> VecBodyes;

public:
	CEphemEPM(LPCTSTR stzDataFolderPath);
	
	int calc_EPM(int pl_num, int centr_num, double dj, double* xv, double* vv);

	bool GetCoord(double date, bool bBaryCenter, AllBodies & coords, bool bGetVelocity);
protected:
	int calc_bar(int pl_num, double dJnd, double* xv, double* vv);

protected:
	VecBodyes		m_vecBodyes;
	static double	s_dRho;
};

